Skip to content

Add MultiQueue (MQ) eviction algorithm - #318

Open
MohammadElsharqawy wants to merge 1 commit into
1a1a11a:developfrom
MohammadElsharqawy:add-multiqueue
Open

Add MultiQueue (MQ) eviction algorithm#318
MohammadElsharqawy wants to merge 1 commit into
1a1a11a:developfrom
MohammadElsharqawy:add-multiqueue

Conversation

@MohammadElsharqawy

@MohammadElsharqawy MohammadElsharqawy commented Jul 31, 2026

Copy link
Copy Markdown

Add MultiQueue (MQ) eviction algorithm

Closes #140

Implements MQ from Zhou, Philbin, Li, "The Multi-Queue Replacement Algorithm for Second Level Buffer Caches" (USENIX ATC 2001). The cache is split into m LRU queues, and an object sits in the queue given by log2(freq). Objects that go untouched past their expire time are demoted one queue down (Adjust()). Evicted ids and frequencies go into a FIFO ghost buffer (Qout), so an object that comes back soon resumes its old frequency instead of restarting at 1.

Files: MQ.c, which follows SLRU's multi-list handling and TwoQ's ghost-buffer pattern. Registration in evictionAlgo.h, CMakeLists.txt, and cache_init.h (as mq / multiqueue). A README entry, and a cacheAlgo_MQ test with ground-truth miss counts.

Parameters (-e): n-queue (8), lifetime in requests (10000), Qout-size-ratio (4.0). -e print shows the defaults.

Validation

  • MQ with n-queue=1 reproduces LRU exactly, as the paper predicts. Both give miss ratio 0.8299 and byte miss ratio 0.9730 on cloudPhysicsIO at 32 MiB.
  • All 30 testEvictionAlgo tests pass (29 existing plus the new one).

Miss ratios

All algorithms run at their own defaults, MQ included (n-queue=8, lifetime=10000, Qout-size-ratio=4.0). Best per column in bold.

data/cloudPhysicsIO.vscsi (113,872 requests):

algo 8 MiB 32 MiB 128 MiB
FIFO 0.8432 0.8319 0.8183
LRU 0.8382 0.8299 0.8180
TwoQ 0.8312 0.8271 0.7980
Sieve 0.8251 0.8201 0.8023
S3FIFO 0.8247 0.8201 0.7897
SLRU 0.8228 0.8155 0.7942
ARC 0.8258 0.8176 0.7848
MQ 0.8269 0.8233 0.8016

data/twitter_cluster52.csv (1,000,000 requests):

algo 1 MiB 8 MiB
LRU 0.2687 0.1652
ARC 0.2648 0.1632
SLRU 0.2517 0.1624
Sieve 0.2514 0.1621
TwoQ 0.2350 0.1696
S3FIFO 0.2336 0.1603
MQ 0.2371 0.1645

MQ beats LRU and FIFO everywhere. Against the newer algorithms it lands mid-pack, which is about what I'd expect from a 2001 algorithm on these workloads. Throughput is roughly 1.0 MQPS against 1.3 for LRU, the cost of the O(m) Adjust() on each access. That still comes out ahead of TwoQ.

Deviations from the paper

1. Qout is byte-budgeted, not entry-count.

The paper sizes the ghost buffer as 4x the number of blocks in the cache. This implementation uses a byte budget instead, the same way TwoQ sizes Aout.

I did try the paper's exact entry-count semantics. It came out equal or worse on every configuration, so I kept the byte budget.

A sweep of the ratio from 0.25 to 16 supports 4.0 as the default. Nothing regresses up to 4, and past that the two traces disagree.

2. lifetime is a fixed parameter.

The paper adapts it at runtime, but defers the mechanism to Zhou's PhD thesis (Princeton, 2000). I couldn't find the thesis, and the 2004 TPDS version points to the same source.

I swept lifetime in powers of two on cloudPhysicsIO at 128 MiB. The miss ratio improves steadily up to 65536 (0.8016 → 0.7703) and is flat beyond it — 131072 and above all give 0.7704. That knee is also where the trace's reuse-distance histogram peaks, which matches what the paper says lifeTime should track. So the right value depends on the workload, and a fixed default won't suit every trace.

I have a prototype adaptive estimator that isn't good enough to ship yet. Happy to open a follow-up with what I found if that's useful.

Closes 1a1a11a#140. Implements Zhou, Philbin, Li (USENIX ATC 2001).
See PR description for validation, benchmarks, and known deviations.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@MohammadElsharqawy

Copy link
Copy Markdown
Author

@haochengxia Noticed the macOS job fails in install_dependency.sh — brew can't find google-perftools. Homebrew renamed that formula to gperftools (it's now at formulae.brew.sh/formula/gperftools), so the brew install glib google-perftools argp-standalone ... line in setup_macOS() needs updating. Happy to open a separate PR for that if ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add MultiQueue

1 participant